﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace psafth.AMB
{
    public static class CRC16
    {
        private static int[] crcTable = new int[256];
        private static int poly = 0x1021; /* x16 + x12 + x5 + 1 generator polynomial */

        /// <summary>
        /// Constructs the CRC16() with it's CRC table.
        /// </summary>
        static CRC16()
        {
            for (int i = 0; i < 256; i++)
            {
                int fcs = 0;
                int d = i << 8;
                for (int k = 0; k < 8; k++)
                {
                    if (((fcs ^ d) & 0x8000) != 0)
                    {
                        fcs = (fcs << 1) ^ poly;
                    }
                    else
                    {
                        fcs = (fcs << 1);
                    }
                    d <<= 1;
                    fcs &= 0xffff;
                }
                crcTable[i] = fcs;
            }
        }

        /// <summary>
        /// Calculates the CRC of a given byte array
        /// </summary>
        /// <param name="b">byte array</param>
        /// <returns>CRC</returns>
        public static uint Calculate(byte[] b)
        {
            // loop, calculating CRC for each byte of the string
            uint work = (uint)0xffff;
            for (int i = 0; i < b.Length; i++)
            {
                work = (uint)((crcTable[((work >> 8)) & 0xff] ^ (work << 8) ^ (b[i] & 0xff)) & 0xffff);
            }
            return work;
        }
    }
}
